#include "../globals/globals.h"
#include "screen.h"

// button intances
/*
bv=auto_info.alliance + auto_info.side=[0,1,2,3]
#define Alliance_RED  -1
#define Alliance_BLUE  1
#define SIDE_LEFT   1
#define SIDE_RIGHT   2
*/
const int BV_MAP[4][2] = {{Alliance_RED, SIDE_LEFT},
                          {Alliance_RED, SIDE_RIGHT},
                          {Alliance_BLUE, SIDE_LEFT},
                          {Alliance_BLUE, SIDE_RIGHT}};

BtnRectangle *auto_side_role_btn[4];
BtnRectangle *vb_route;
BtnRectangle *vb_auto;
BtnRectangle *vb_gyro_rec;

void controller_print_team_number_and_autoinfo() {
  ctrl.Screen.clearLine(3);
  string s = "";

  if (auto_info.isAlliance(Alliance::blue))
    s += "B-";
  else
    s += "R-";
  if (auto_info.isSide(Side::left))
    s += "L-";
  else
    s += "R-";

  extern bool AUTO_TEST;
  extern bool RUN_SKILLS;
  if (AUTO_TEST)
    s += "T";
  else if (RUN_SKILLS)
    s += "S";

  char c[25];
  if (AUTO_TEST || RUN_SKILLS)
    sprintf(c, "%s   %s", s.c_str(), team_name.c_str());
  else
    sprintf(c, "%s%d   %s", s.c_str(), auto_info.route_number,
            team_name.c_str());

  ctrl.Screen.setCursor(3, 1);
  ctrl.Screen.print("%s", c);
}

int cur_bv_highting; //指示当前高亮的按钮
/////////////////////////////////////////////////

void update_auto_info_display() {
  int line_x = 260;
  int line_y = 67;
  int LETTER_WIDTH = 17;

  screen_set_pen_color(color::white);
  screen_set_pen_font(fontType::mono30);

  Brain.Screen.printAt(line_x, line_y, "Auto: ");

  if (auto_info.isAlliance(Alliance::red))
    screen_set_pen_color(color::red);
  else
    screen_set_pen_color(color::blue);

  if (auto_info.isAlliance(Alliance::red))
    Brain.Screen.printAt(line_x + 5 * LETTER_WIDTH, line_y, "R—");
  else
    Brain.Screen.printAt(line_x + 5 * LETTER_WIDTH, line_y, "B—");

  if (auto_info.isSide(Side::left))
    Brain.Screen.printAt(line_x + 7 * LETTER_WIDTH, line_y, "L—");
  else
    Brain.Screen.printAt(line_x + 7 * LETTER_WIDTH, line_y, "R—");

  extern bool AUTO_TEST;
  extern bool RUN_SKILLS;
  screen_set_pen_color(color::cyan);
  if (AUTO_TEST)
    Brain.Screen.printAt(line_x + 9 * LETTER_WIDTH, line_y, "T ");
  else if (RUN_SKILLS)
    Brain.Screen.printAt(line_x + 9 * LETTER_WIDTH, line_y, "S ");
  else
    Brain.Screen.printAt(line_x + 9 * LETTER_WIDTH, line_y, "%d ",
                         auto_info.route_number);

  controller_print_team_number_and_autoinfo(); //恢复遥控第三行显示
}
////////////////////////////////////////////////////////////////////////////////
void route_number_roll_over() {
  if (auto_info.isSide(Side::left) &&
      auto_info.route_number > SIDE_LEFT_MAX_AUTO_NUMBER)
    auto_info.route_number = 1;
  if (auto_info.isSide(Side::right) &&
      auto_info.route_number > SIDE_RIGHT_MAX_AUTO_NUMBER)
    auto_info.route_number = 1;

  if (auto_info.route_number <= 0) {
    if (auto_info.isSide(Side::right))
      auto_info.route_number = SIDE_RIGHT_MAX_AUTO_NUMBER;
    if (auto_info.isSide(Side::left))
      auto_info.route_number = SIDE_LEFT_MAX_AUTO_NUMBER;
  }
}
////////////////////////////////////////////////////////////////////////////////
void route_number_button_press_callback(BtnShape *p_this_btn) {
  p_this_btn->brighter();
  auto_info.route_number++;
  route_number_roll_over();
  update_auto_info_display();
}
void route_number_button_release_callback(BtnShape *p_this_btn) {
  p_this_btn->darker();
}

////////////////////////////////////////////////////////////////////////////////
void auto_side_role_button_press_callback(BtnShape *p_this_btn) {
  //强制取消测试程序
  extern bool AUTO_TEST;
  AUTO_TEST = 0;

  //防止同一按键按下会继续执行选场代码
  if (!p_this_btn->is_on_brighter()) {
    auto_info.alliance =
        Alliance(BV_MAP[p_this_btn->get_id()][0]); //根据按钮获取选场信息
    auto_info.side = Side(BV_MAP[p_this_btn->get_id()][1]);

    auto_side_role_btn[cur_bv_highting]->darker(); //当前高亮的按钮变暗
    cur_bv_highting =
        (int)auto_info.alliance + (int)auto_info.side; //更新cur_bv_highting
    p_this_btn->brighter();
    route_number_roll_over();
    update_auto_info_display();
    if (auto_info.isAlliance(Alliance::red))
      vb_route->set_color_fill(red);
    else
      vb_route->set_color_fill(blue);
  }
}

////////////////////////////////////////////////////////////////////////////////
//根据手动修改auto_info后的值来更新选场按钮的显示
void update_side_role_button_according_to_auto_info() {
  //如果当前本身就是高亮状态，则不需要切换
  if (cur_bv_highting != (int)auto_info.alliance + (int)auto_info.side) {
    auto_side_role_btn[cur_bv_highting]->darker(); //当前高亮的按钮变暗
    cur_bv_highting =
        (int)auto_info.alliance + (int)auto_info.side; //更新cur_bv_highting
    auto_side_role_btn[cur_bv_highting]->brighter();
  }

  if (auto_info.isAlliance(Alliance::red))
    vb_route->set_color_fill(red);
  else
    vb_route->set_color_fill(blue);
  update_auto_info_display();
}
/////////////////////////////////////////
void buttons_init() {
  static bool inited = false;
  if (!inited) {
    int width = 108, height = 45, space_x = 8;
    int column_1 = 252, column_2 = column_1 + width + space_x;
    int row_1 = 125, row_2 = row_1 + height + 15;

    cur_bv_highting = (int)auto_info.alliance + (int)auto_info.side;

    // bv=0
    static BtnRectangle vb_red1(column_1, row_1, width, height,
                                cur_bv_highting == 0, color::white, color::red,
                                "RED LEFT"); // bv:0
    auto_side_role_btn[0] = &vb_red1;

    // bv=1
    static BtnRectangle vb_red2(column_2, row_1, width, height,
                                cur_bv_highting == 1, color::white, color::red,
                                "RED RIGHT"); // bv:1
    auto_side_role_btn[1] = &vb_red2;

    // bv=2
    static BtnRectangle vb_blue1(column_1, row_2, width, height,
                                 cur_bv_highting == 2, color::white,
                                 color::blue,
                                 "BLUE LEFT"); // bv:2
    auto_side_role_btn[2] = &vb_blue1;

    // bv=3
    static BtnRectangle vb_blue2(column_2, row_2, width, height,
                                 cur_bv_highting == 3, color::white,
                                 color::blue,
                                 "BLUE RIGHT"); // bv:3
    auto_side_role_btn[3] = &vb_blue2;

    for (int k = 0; k < 4; k++) {
      auto_side_role_btn[k]->set_id(k);
      auto_side_role_btn[k]->register_press_callback(
          auto_side_role_button_press_callback);
    }
    color c_fill;
    if (auto_info.isAlliance(Alliance::red))
      c_fill = red;
    else
      c_fill = blue;

    static BtnRectangle vb_route_tmp(
        column_1, row_1 - height - 2, width * 2 + space_x, height - 10, false,
        color::white, c_fill, "ROUTE", fontType::mono20, cyan);
    vb_route = &vb_route_tmp;
    vb_route->register_press_callback(route_number_button_press_callback);
    vb_route->register_release_callback(route_number_button_release_callback);

    //////////////////////////////
    static BtnRectangle btn_gyro_racallibrate(
        column_1, 6, width, 35, false, color::white, color::orange,
        "imu calibrate", fontType::mono15, color::white);
    static BtnRectangle btn_auto_start(
        column_2, 6, width, 35, false, color::white, color::orange,
        "start auto", fontType::mono15, color::white);
    vb_auto = &btn_auto_start;
    vb_gyro_rec = &btn_gyro_racallibrate;
    inited = true;
  } else
    buttons_show_up();
  update_auto_info_display();
}
////////////////////////////////////////////////////////////////
void buttons_show_up() {
  for (auto b : auto_side_role_btn)
    b->show_up();
  vb_route->show_up();
  vb_auto->show_up();
  vb_gyro_rec->show_up();
  update_auto_info_display();
}

void buttons_show_hide() {
  for (auto b : auto_side_role_btn)
    b->hide();
  vb_route->hide();
  vb_auto->hide();
  vb_gyro_rec->hide();
}